package rlm;

import linearProgramming.Variable;
import rlm.constraints.Directions;
import alm.LayoutSpec;
import alm.XTab;
import alm.YTab;

public class TabBounds {
	private YTab topTab, bottomTab;
	private XTab leftTab, rightTab;

	public YTab getTopTab() {
		return topTab;
	}

	public void setTopTab(YTab topTab) {
//		System.out.println("\tTop tab "+topTab + " to "+getName()+", was: "+this.topTab);
		this.topTab = topTab;
	}

	public YTab getBottomTab() {
		return bottomTab;
	}

	public void setBottomTab(YTab bottomTab) {
//		System.out.println("\tBottom tab "+bottomTab + " to "+getName()+", was: "+this.bottomTab);
		this.bottomTab = bottomTab;
	}

	public XTab getLeftTab() {
		return leftTab;
	}

	public void setLeftTab(XTab leftTab) {
		this.leftTab = leftTab;
	}

	public XTab getRightTab() {
		return rightTab;
	}

	public void setRightTab(XTab rightTab) {
		this.rightTab = rightTab;
	}

	/**
	 * TODO:: replace this function with a map<Direction, Variable> that returns
	 * the correct sub class of variable (X or Y) for each direction
	 * @param dir
	 * @return
	 */
	public Variable getTab(Directions dir){
		switch(dir){
		case Bottom: return getBottomTab();
		case Top: return getTopTab();
		case Left: return getLeftTab();
		case Right: return getRightTab();
		default: return null;
		}
	}

	
	public Variable getTab(Directions dir, LayoutSpec ls){
		switch(dir){
		case Bottom: return ls.getBottom();
		case Top: return ls.getTop();
		case Left: return ls.getLeft();
		case Right: return ls.getRight();
		default: return null;
		}		
	}
	
	public void setTab(Directions dir, Variable tab){
		if (dir == Directions.Bottom)
			setBottomTab((YTab) tab);
		if (dir == Directions.Left)
			setLeftTab((XTab) tab);
		if (dir == Directions.Right)
			setRightTab((XTab) tab);
		if (dir == Directions.Top)
			setTopTab((YTab) tab);
		
	}

	
	public boolean isComplete() {

		boolean b = getBottomTab() != null && getTopTab() != null
				&& getLeftTab() != null && getRightTab() != null;
		return b;
	}

	public String toString(){
		return "["+getLeftTab() +","+ getTopTab()+","+ getRightTab()+","+ getBottomTab()+"]";
	}
	
	public Variable testAndSet(Directions dir, LayoutSpec ls){
		if (getTab(dir) == null){
			if (dir == Directions.Top || dir == Directions.Bottom)
				setTab(dir, ls.addYTab());
			else
				setTab(dir, ls.addXTab());
		}
		
		return getTab(dir);
	}
	
	public void testAndSetAll(LayoutSpec ls){
		for(Directions dir : Directions.values()){
			testAndSet(dir, ls);
		}
	}
	
	// TODO :: find a more suitable name for this function
	public void setDefaultBounds(LayoutSpec ls) {		
		for(Directions dir : Directions.values()){
			if (getTab(dir) == null)
				setTab(dir, getTab(dir, ls));
		}
	}
	
//	public <Tab extensd Variable> Tab getOtherDirection(Directions)
	
}
